package com.sw.c.aop;

import com.alibaba.fastjson.JSON;
import com.sw.c.annotations.SystemLogAnnotation;
import com.sw.c.mapper.LogAopDao;
import com.sw.c.pojo.entity.SysLog;
import com.sw.c.utils.DateUtil;
import com.sw.c.utils.IPAndUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;


@Slf4j
@Aspect
@Component
public class  LogOpAspect {
    private SysLog sysLog = new SysLog();
    @Resource
    private LogAopDao logAopDao;
    private  Date stm;
    private  Date etm;
    /**
     * 功能描述: 切点
     */
    @Pointcut("@annotation(com.sw.c.annotations.SystemLogAnnotation)")
    public void executePointCut() {
    }

    /**
     * 功能描述: 请求前执行
     */
    @Before("executePointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        try {
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            // 主键
            sysLog.setId(UUID.randomUUID().toString());
            //  操作时间
            stm = new Date();
            sysLog.setStartTime(DateUtil.formatDateToString(stm, null));
            //  接口地址
            sysLog.setUrl(request.getRequestURL().toString());
            //  接口名
            sysLog.setTargetName(joinPoint.getTarget().getClass().getName());
            //  接口方法
            sysLog.setMethodName(joinPoint.getSignature().getName());
            //  操作名称
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            SystemLogAnnotation annotation = signature.getMethod().getAnnotation(SystemLogAnnotation.class);
            sysLog.setOperationName(annotation.operationName());
            //业务类型
            sysLog.setBusinessType(annotation.businessType());
            //  请求参数  参数注释掉，因为存储占用太大
            Object[] objects = joinPoint.getArgs();
            String params = "";
            if (objects != null && objects.length > 0) {
                params = JSON.toJSONString(joinPoint.getArgs());
            }
            sysLog.setParams(params);
            //  请求ip
            sysLog.setIp(IPAndUserUtil.getReqIp(request));
            //后续通过调用外部接口获取登录用户信息进行补充，临时写死
//            sysLog.setUserId(IPAndUserUtil.getUser(request).get("username")+"");
            sysLog.setUserId("10086");
            sysLog.setDept("管理员");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 请求后执行
     */
    @AfterReturning(returning = "ret", pointcut = "executePointCut()")
    public void doAfterReturning(Object ret) throws Throwable {
        try {
            // 处理完请求，返回内容  参数注释掉，因为存储占用太大
//            sysLog.setReturnData(JSON.toJSONString(ret));
            //  方法结束时间
            etm = new Date();
            sysLog.setEndTime(DateUtil.formatDateToString(etm, null));
            //  计算方法执行时间
            long excuteTime = etm.getTime() - stm.getTime();
            sysLog.setExcuteTime(excuteTime);
            //保存日志
            logAopDao.insertLog(sysLog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
